package com.xzj.admin.auth.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSONObject;
import com.xzj.admin.auth.service.AdminAuthService;
import com.xzj.admin.base.domain.SysUserInfo;
import com.xzj.admin.boot.api.service.AdminBootService;
import com.xzj.common.core.constants.Constants;
import com.xzj.common.core.domain.vo.R;
import com.xzj.common.core.exception.ServiceException;
import com.xzj.common.secure.util.XzjSecureUtil;
import jakarta.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

/**
 * @program: xzj-admin
 * @ClassName: AdminAuthServiceImpl
 * @description: 认证服务
 * @author: XiaZunJun
 * @create: 2024-08-02 14:08
 */
@Service
public class AdminAuthServiceImpl implements AdminAuthService {

    private static final Logger log = LoggerFactory.getLogger(AdminAuthServiceImpl.class);
    @Resource
    private AdminBootService adminBootService;

    /**
     * 处理用户登录请求
     *
     * @param sysUserInfo 包含用户登录信息的SysUserInfo对象
     * @return 登录成功后的SysUserInfo对象，包含用户的ID和令牌信息
     * @throws RuntimeException 如果用户名或密码为空，或登录失败
     */
    @Override
    public SysUserInfo login(SysUserInfo sysUserInfo) {
        // 检查用户名和密码是否为空
        if(StrUtil.isAllNotEmpty(sysUserInfo.getUsername(),sysUserInfo.getUsername())){
            // 根据用户名获取用户信息
            R r = adminBootService.userInfoByName(sysUserInfo.getUsername());
            // 检查获取用户信息是否成功
            if(Constants.SUCCESS.equals(r.getStatus()) && null != r.getResult()){
                // 获取用户信息数据
                SysUserInfo data = JSONObject.from(r.getResult()).to(SysUserInfo.class);
                // 对用户输入的密码进行加密
                String cipherPass = XzjSecureUtil.aesEncrypt(sysUserInfo.getPassword());
                // 检查加密后的密码是否与数据库中的密码匹配
                if(cipherPass.equals(data.getPassword())){
                    // 用户登录，设置用户ID
                    StpUtil.login(data.getUserId());
                    // 获取登录后的令牌信息
                    String tokenValue = StpUtil.getTokenInfo().getTokenValue();
                    // 将令牌信息设置到用户对象中
                    data.setToken(tokenValue);
                    // 返回登录成功后的用户对象
                    return data;
                }else{
                    throw new RuntimeException("用户名或密码错误");
                }
            }
            // 抛出异常，表示用户名或密码错误
            throw new RuntimeException("用户不存在");
        }else{
            throw new RuntimeException("用户名与密码缺失");
        }
    }


    @Override
    public void logout() {
        StpUtil.logout();
    }

    @Override
    public SysUserInfo getUserInfo() {
        String loginId = (String) StpUtil.getTokenInfo().getLoginId();
        R r = adminBootService.userInfoById(loginId);
        // 检查获取用户信息是否成功
        if(Constants.SUCCESS.equals(r.getStatus()) && null != r.getResult()){
            // 获取用户信息数据
            // 返回登录成功后的用户对象
            return JSONObject.from(r.getResult()).to(SysUserInfo.class);
        }else{
            throw new ServiceException("10010","用户不存在");
        }
    }

    @Override
    public R getMenuList() {
        String loginId = (String) StpUtil.getTokenInfo().getLoginId();
        R r = adminBootService.menuList(loginId);
        if(Constants.SUCCESS.equals(r.getStatus())){
            return r;
        }else{
            throw new ServiceException("10010","获取菜单失败！");
        }
    }

    @Override
    public R getPermCode() {
        String loginId = (String) StpUtil.getTokenInfo().getLoginId();
        R r = adminBootService.perCodeList(loginId);
        if(Constants.SUCCESS.equals(r.getStatus())){
            return r;
        }else{
            throw new ServiceException("10010","获取权限失败！");
        }
    }
}
